﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows.Forms;

using FileStorage;
using FileStorage.Caching;
using FileStorage.Caching.CacheContainers;
using FileStorage.Comparing;
using FileStorage.Comparing.Comparers;
using FileStorage.Enums.Behaviours;
using FileStorage.Helper;
using FileStorage.MetaData;

namespace FileStorageGUI
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private string filestorageName;
        private Guid selectedDataIdentifier;
        private static String tempPath = Path.GetTempPath();
        private static String tempPathFileData = (tempPath + @"\tempfilestorepreview").Replace(@"\\", @"\");
        
        private void Form1_Load(object sender, EventArgs e)
        {
            temporaryFileStoreLocationTextboxB.Text = tempPathFileData;

            string[] args = Environment.GetCommandLineArgs();
            // index 0 is the entire line
            if (args.Count() > 1)
            {
                // @"H:\Proj\Pveh\Kadaster\NFileStorages\6-1";
                filestorageName = args[1];
                filestorageName = filestorageName.ToLowerInvariant();
                filestorageName = filestorageName.Replace(".filestorage.data.fc", "");
                filestorageName = filestorageName.Replace(".filestorage.index.fc", "");

                ReloadFilestorage();
            }
            else
            {
                //
                // 
                //
                System.Windows.Forms.MessageBox.Show("This application requires a filestore name as a parameter;\r\nFileStorageGUI YourName");
                Application.Exit();
            }
        }

        private void ReloadFilestorage()
        {
            dataIdentifiers.Items.Clear();

            List<Guid> theDataIdentifiers = FileStorageFacade.GetAllDataIdentifiersBasedUponFileStorageIndexFile(filestorageName);
            foreach (var item in theDataIdentifiers)
            {
                string text = item + "/" + (item.ToNFileStorageOrigFileName());
                dataIdentifiers.Items.Add(text);
            }

            fileStoragelabel.Text = filestorageName;
            filestorageCount.Text = theDataIdentifiers.Count + " items found";
        }

        private void dataIdentifiers_SelectedValueChanged(object sender, EventArgs e)
        {
            string selectedItem = dataIdentifiers.SelectedItem as string;
            if (selectedItem != null)
            {
                SaveSelectedItemButtonAs.Enabled = true;
                selectedDataIdentifierTextBox.Text = selectedItem;
                string[] splittedSelectedItem = selectedItem.Split("/".ToCharArray());
                if (splittedSelectedItem.Count() > 1)
                {
                    this.selectedDataIdentifier = new Guid(splittedSelectedItem[0]);
                    DrawData();
                    DrawMetadata();
                }
            }
            else
            {
                SaveSelectedItemButtonAs.Enabled = false;
                selectedDataIdentifierTextBox.Text = "";
            }
        }

        private void DrawData()
        {
            byte[] datablock = FileStorageFacade.GetBytesData(filestorageName, selectedDataIdentifier);
            itemSizeInBytes.Text = datablock.Count() + " bytes";
            DrawImage();
            DrawText();
            DrawWeb();
        }

        private void DrawMetadata()
        {
            MetaDataContainer metaDataContainer = FileStorageFacade.GetMetaData(filestorageName, selectedDataIdentifier);
            metaDataTopLabel.Text = metaDataContainer.CustomMetaData.GetType().ToString();
            creationDateUTCLabel.Text = metaDataContainer.CreationDateUTC.ToString();
            metaDataVisualizationTextBox.Text = metaDataContainer.CustomMetaData.GetInfo();
        }

        private void DrawImage()
        {
            try
            {
                using (Stream s = FileStorageFacade.GetStreamData(filestorageName, selectedDataIdentifier))
                {
                    Image i = Image.FromStream(s);
                    imageControl.Image = i;
                    noValidImageLabel.Visible = false;
                    imageControl.Visible = true;
                }
                
            }
            catch (Exception)
            {
                noValidImageLabel.Visible = true;
                imageControl.Visible = false;
            }
        }

        private void DrawText()
        {
            try
            {
                string s = FileStorageFacade.GetStringData(filestorageName, selectedDataIdentifier);
                dataTextBox.Text = s;
            }
            catch (Exception)
            {
            }
        }

        private void DrawWeb()
        {
            if (isWebTagPreviewEnabled.Checked)
            {
                try
                {
                    string filename;
                    if (pdfPreviewRadioButton.Checked)
                    {
                        filename = tempPathFileData + ".pdf";
                    } 
                    else
                    {
                        filename = tempPathFileData;
                    }
                    FileStorageFacade.ExportToFile(filestorageName, selectedDataIdentifier, filename, ExportFileBehaviour.OverrideWhenAlreadyExists);
                    Uri uri = new Uri(filename);
                    
                    webBrowserPreviewData.Navigate(uri, null, null, null);
                    webBrowserPreviewData.Visible = true;
                }
                catch (Exception e)
                {
                    MessageBox.Show(e.ToString());
                }
            } 
            else
            {
                webBrowserPreviewData.Visible = false;
            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            Dictionary<Guid, List<Guid>> duplicates = FileStorageCompareFacade.GetDuplicates(filestorageName, DataIdentifierComparerFactory.Md5ContentsComparer, CacheContainerFactory.CreateNonExpiringCacheContainer());

            dataIdentifiers.Items.Clear();

            List<Guid> theDataIdentifiers = 
                (from duplicate in duplicates.Keys
                 where duplicates[duplicate].Count > 0
                 select duplicate).ToList();
            foreach (var item in theDataIdentifiers)
            {
                string text = item + "/" + (item.ToNFileStorageOrigFileName());
                dataIdentifiers.Items.Add(text);
            }

            fileStoragelabel.Text = filestorageName;
            filestorageCount.Text = theDataIdentifiers.Count + " items found";
        }

        private void SaveSelectedItemButtonAs_Click(object sender, EventArgs e)
        {
            saveFileDialog1.FileName = selectedDataIdentifier.ToString();
            DialogResult dialogResult = saveFileDialog1.ShowDialog();
            switch (dialogResult)
            {
                case DialogResult.OK:
                    string filename = saveFileDialog1.FileName;
                    if (File.Exists(filename))
                    {
                        System.Windows.Forms.DialogResult overwriteDialogResult = MessageBox.Show("File already exists, do you want to overwrite it?", "", MessageBoxButtons.YesNoCancel);
                        switch (overwriteDialogResult)
                        {
                            case System.Windows.Forms.DialogResult.Yes:
                                FileStorageFacade.ExportToFile(filestorageName, selectedDataIdentifier, filename, ExportFileBehaviour.OverrideWhenAlreadyExists);
                                break;
                        }
                    } 
                    else
                    {
                        FileStorageFacade.ExportToFile(filestorageName, selectedDataIdentifier, filename, ExportFileBehaviour.ThrowExceptionWhenAlreadyExists);
                    }
                    break;
                default:
                    break;
            }
        }
    }
}
